package com.gopay.cashier.service.impl;

import java.util.*;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.gopay.cashier.domain.bean.PayChannelDtlBean;
import com.gopay.cashier.domain.bean.PayChannelWayBean;
import com.gopay.cashier.service.SoluBisPayChannelService;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.constants.trans.PayChannel;
import com.gopay.common.constants.trans.PayChannelType;
import com.gopay.common.constants.txncd.IntTxnCd;
import com.gopay.common.domain.bank.payconfig.PayConfigRequest;
import com.gopay.common.domain.bank.payconfig.PayConfigResult;
import com.gopay.common.domain.bank.payconfig.bo.PayConfigInfo;
import com.gopay.common.domain.solution.SolutionRequest;
import com.gopay.common.domain.solution.SolutionResponse;
import com.gopay.common.domain.view.config.ViewSolutionPaychannelTab;
import com.gopay.common.domain.view.config.ViewSolutionTransView;
import com.gopay.common.util.JsonUtils;
import com.gopay.remote.bank.PayConfigRemoteService;
import com.gopay.remote.solution.SolutionRemoteService;
import com.gopay.remote.solution.vo.PayChannelDtlInfo;

@Service
public class SoluBisPayChannelServiceImpl implements SoluBisPayChannelService {

	private static Map<String, String> payChannelLabel = new HashMap<String, String>();
	
	private static Logger log = Logger.getLogger(SoluBisPayChannelServiceImpl.class);
	
	@Autowired
    PayConfigRemoteService  bisBankPayConfig;
	
	@Autowired
    SolutionRemoteService uiConfigService;
	
	@Autowired
    SolutionRemoteService transPayChanService;
    
	@Override
	public PayChannelWayBean getSoluBisPayChannel(String intTxnCd, String acctId) {
		
		PayChannelWayBean pwb = new PayChannelWayBean();
    	
    	//BIS银行产品
    	List<PayConfigInfo> bisBankList = getBisBankList(intTxnCd);
 //   	log.info("load bis bank :"+getJsonString(bisBankList));
    	//收银台展示方案
    	List<ViewSolutionPaychannelTab> soluPayChannelViewList = getSoluPayChannelList(intTxnCd, acctId,pwb);
 //   	log.info("load solution tab :"+getJsonString(soluPayChannelViewList));
    	//清算渠道方案
    	List<PayChannelDtlInfo> soluPayChannelList = getPayChannelDtlList(intTxnCd, acctId);
 //   	log.info("load solution bank :"+getJsonString(soluPayChannelList));
    	
    	List<PayChannelDtlBean> payChannelList = new ArrayList<PayChannelDtlBean>();
    	
    	if(soluPayChannelList!=null && soluPayChannelList.size()>0
				&& soluPayChannelViewList != null && soluPayChannelViewList.size() > 0){
    		for(ViewSolutionPaychannelTab soluPayChannel :soluPayChannelViewList){
    			if(StringUtils.equals(soluPayChannel.getPayChannelId(), PayChannelType.GFB_PAY.value)){
    				PayChannelDtlBean bean = new PayChannelDtlBean();
    				bean.setPayChannelName(soluPayChannel.getPayChannelDesc());
    				bean.setPayChannelIndex(soluPayChannel.getOrder());
    				bean.setPayChannelType(PayChannelType.GFB_PAY.value);
    				bean.setPayChannelLabelId(payChannelLabel.get(PayChannelType.GFB_PAY.value));
                    bean.setPayChannelName("账户支付");
    				payChannelList.add(bean);
    			}else if((bisBankList!=null && bisBankList.size()>0) && (soluPayChannelList!=null && soluPayChannelList.size()>0)){
					PayChannelDtlBean bean = getPayChannelBean(bisBankList, soluPayChannel, soluPayChannelList);
	    			if(bean!=null && (bean.getBankCodes()!=null && bean.getBankCodes().size()>0)){
	    				payChannelList.add(bean);
	    			}
    			}
    		}
    	}
    	pwb.setPayChannelList(payChannelList);
    	
		return pwb;
	}


    private List<PayConfigInfo> getBisBankList(String intTxnCd){
    	List<PayConfigInfo> bisBankList = null;
    	PayConfigRequest request = new PayConfigRequest();
		request.setIntTxnCd(IntTxnCd.get(intTxnCd));
		PayConfigResult result = bisBankPayConfig.payConfig(request);
		if(result!=null && StringUtils.equals(result.getResultCode(), ProcCodeConstants.PROC_CODE_100S1000)){
			bisBankList = result.getConfigs();
		}
		
		if(bisBankList==null || bisBankList.size()==0){
			log.error("can't get bis bank for intTxnCd:"+intTxnCd);
			return null;
		}
		return bisBankList;
    }
    
    private  List<ViewSolutionPaychannelTab> getSoluPayChannelList(String intTxnCd,String acctId,PayChannelWayBean pwb){
    	SolutionRequest request = new SolutionRequest();
		request.setAcctId(acctId);
		request.setRequest(intTxnCd);
		SolutionResponse resp =  uiConfigService.resolve(request);
		if(resp==null || resp.getResponse() == null) 
			return null;
		
		ViewSolutionTransView view = (ViewSolutionTransView) resp.getResponse();
		List<ViewSolutionPaychannelTab> tabs = view.getTabs();
		
		if(tabs==null || tabs.size()==0) {
			log.error("can't get payChannel solution for intTxnCd:"+intTxnCd+" acctId:"+acctId);
			return null;
		}
		pwb.setDefalutPayUserType(view.getDefalutPayUserType());
		return tabs;
    }
    

    private PayChannelDtlBean getPayChannelBean(List<PayConfigInfo> bisBankList,ViewSolutionPaychannelTab soluPayChannel,List<PayChannelDtlInfo> soluPayChannelList){
    	PayChannelDtlBean bean = new PayChannelDtlBean();
    	bean.setPayChannelIndex(soluPayChannel.getOrder());
    	bean.setPayChannelName(soluPayChannel.getPayChannelDesc());
    	for(PayConfigInfo bis :bisBankList){
    		getChannelBanks(soluPayChannel, bis, soluPayChannelList,bean);
    	}
    	return bean;
    }
    
    
    private void getChannelBanks(ViewSolutionPaychannelTab tab,PayConfigInfo bis,List<PayChannelDtlInfo> soluPayChannelList,PayChannelDtlBean bean){
    	if(StringUtils.equals(tab.getPayChannelId(), PayChannelType.OUTSTLM_PAY.value)){
            //网银支付
    		bean.setPayChannelType(PayChannelType.OUTSTLM_PAY.value);
    		bean.setPayChannelLabelId(payChannelLabel.get(PayChannelType.OUTSTLM_PAY.value));
    		//网银支付
    		if(StringUtils.equals(bis.getBankBizProd(), BisBankBusinessProd._00.value)){
    			//01-个人网银支付
    			List<PayChannelDtlInfo> perBanks = getPayBanks(bis, getPayChDtlByChId(PayChannel._01, soluPayChannelList));
    			if(perBanks!=null && perBanks.size()>0){
    				bean.putBankCodes(PayChannel._01.value, perBanks);
    			}
    		}else if(StringUtils.equals(bis.getBankBizProd(), BisBankBusinessProd._01.value)){
    			//51-企业网银支付
    			List<PayChannelDtlInfo> corBanks = getPayBanks(bis,getPayChDtlByChId(PayChannel._51, soluPayChannelList));
    			if(corBanks!=null && corBanks.size()>0){
    				bean.putBankCodes(PayChannel._51.value, corBanks);
    			}
    		}
            bean.setPayChannelName("网银支付");
    	} else if(StringUtils.equals(tab.getPayChannelId(), PayChannelType.FAST_PAY.value) ){
            if(StringUtils.equals(bis.getBankBizProd(), BisBankBusinessProd._05.value)){
                //06-个人信用卡快捷付款
                List<PayChannelDtlInfo> bp06 = getPayBanks(bis,getPayChDtlByChId(PayChannel._06, soluPayChannelList));
                if(bp06!=null && bp06.size()>0){
                    bean.putBankCodes(PayChannel._06.value, bp06);
                }
            }else if(StringUtils.equals(bis.getBankBizProd(), BisBankBusinessProd._15.value)){
                //03-个人借记卡快捷付款
                List<PayChannelDtlInfo> bp03 = getPayBanks(bis,getPayChDtlByChId(PayChannel._03, soluPayChannelList));
                if(bp03!=null && bp03.size()>0){
                    bean.putBankCodes(PayChannel._03.value, bp03);
                }
            }
    		bean.setPayChannelType(PayChannelType.FAST_PAY.value);
    		bean.setPayChannelLabelId(payChannelLabel.get(PayChannelType.FAST_PAY.value));
            bean.setPayChannelName("快捷支付");
    	} else if(StringUtils.equals(tab.getPayChannelId(), PayChannelType.SCAN_PAY.value) ){
			//扫码支付
			if(StringUtils.equals(bis.getBankBizProd(), BisBankBusinessProd._16.value)){
				//三方扫码支付
				List<PayChannelDtlInfo> bp16 = getPayBanks(bis,getPayChDtlByChId(PayChannel._16, soluPayChannelList));
				if(bp16!=null && bp16.size() > 0){
					bean.putBankCodes(PayChannel._16.value, bp16);
				}
			}else if(StringUtils.equals(bis.getBankBizProd(), BisBankBusinessProd._17.value)){
				//三方APP支付
				List<PayChannelDtlInfo> bp17 = getPayBanks(bis,getPayChDtlByChId(PayChannel._17, soluPayChannelList));
				if(bp17 != null && bp17.size() > 0){
					bean.putBankCodes(PayChannel._17.value, bp17);
				}
			}
			bean.setPayChannelType(PayChannelType.SCAN_PAY.value);
			bean.setPayChannelLabelId(payChannelLabel.get(PayChannelType.SCAN_PAY.value));
			bean.setPayChannelName("扫码支付");
		}
    }
    
    private List<PayChannelDtlInfo> getPayChDtlByChId(PayChannel pc,List<PayChannelDtlInfo> soluPayChannelList){
    	List<PayChannelDtlInfo> lp = new ArrayList<PayChannelDtlInfo>();
    	for(PayChannelDtlInfo p :soluPayChannelList){
    		if(StringUtils.equals(p.getPayChannel(), pc.value)){
    			lp.add(p);
    		}
    	}
    	return lp;
    }
    
    private List<PayChannelDtlInfo> getPayBanks(PayConfigInfo bis,List<PayChannelDtlInfo> payChDtlList){
        List<PayChannelDtlInfo> newBankList = new LinkedList<PayChannelDtlInfo>();
        List<String> bisBankCodes = formatBankCode(bis.getBankCodes());
        //取银行交集并根据bis银行数据进行排序
        for(String code : bisBankCodes){
            for(PayChannelDtlInfo bank : payChDtlList){
                if(StringUtils.equals(code.toUpperCase(),bank.getOutStlmId().toUpperCase())){
                    newBankList.add(bank);
                }
            }
        }
        return newBankList;
    }
    
    private List<String> formatBankCode(List<String> bankCodes){
    	List<String> bankCodeList = new LinkedList<String>();
    	if(bankCodes!=null && bankCodes.size()>0){
    		for(String code : bankCodes){
    			if(StringUtils.isNotBlank(code)){
    				bankCodeList.add(code.toUpperCase());
    			}
    		}
    	}
    	return bankCodeList;
    }
    
    private List<PayChannelDtlInfo> getPayChannelDtlList(String intTxnCd,String acctId){
    	List<PayChannelDtlInfo> payChannelList = null;
    	SolutionRequest request = new SolutionRequest();
		request.setAcctId(acctId);
		request.setRequest(intTxnCd);
		SolutionResponse resp =  transPayChanService.resolve(request);
		if(resp==null){
			log.error("get solution banks response is null  for intTxnCd:"+intTxnCd+" acctId:"+acctId);
			return null;
		}
		
		PayChannelDtlInfo[] ps = (PayChannelDtlInfo[]) resp.getResponse();
		if(ps==null || ps.length==0){
			log.error("get solution banks response is null  for intTxnCd:"+intTxnCd+" acctId:"+acctId);
			return null;
		}
		
		payChannelList = new ArrayList<PayChannelDtlInfo>();
		for (PayChannelDtlInfo p : ps) {
			payChannelList.add(p);
		}
		return payChannelList;
    }
    
    static{
    	payChannelLabel.put(PayChannelType.OUTSTLM_PAY.value, "bankChannelSel");
    	payChannelLabel.put(PayChannelType.GFB_PAY.value, "gopayChannelSel");
    	payChannelLabel.put(PayChannelType.FAST_PAY.value, "expressChannelSel");
    	payChannelLabel.put(PayChannelType.SCAN_PAY.value, "scanChannelSel");
    }
    
    private String  getJsonString(Object obj){
    	try {
			return JsonUtils.toJson(obj).toString();
		} catch (Exception e) {
			
		}
    	return null;
    }
}
